
var Module = Class.create({
   initialize: function(name, area, compCredits, optCredits, desc) {
       this.name = name;
       this.area = area;
       this.maxCompCredits = parseInt(compCredits);
       this.maxOptCredits = parseInt(optCredits);
       this.desc = Local.module_description[this.area];

       this.compCredits = 0;
       this.optCredits = 0;
       this.grade = 0;
       
       this.moduleExam = false;
       this.oralExam = false;
       
       Globals.modules[area] = this;
       this.display();
   },
   
    createDiv: function() {
        var newDiv = Builder.node('div', {id: 'mod' + this.area, className: 'module' }, [
            Builder.node('p', {className: 'handle'}, this.name),
            Builder.node('div', {className: 'help', onClick: 'Message.moduleHelp("'+this.area+'");'}),
            Builder.node('p', {id: "compfield"+this.area, className: 'modects1'}, 'Compulsory: 0 / '+this.compCredits),
            Builder.node('p', {id: "optfield"+this.area, className: 'modects2'}, 'Optional: 0 / '+this.optCredits),
            Builder.node('div', {className: 'modexam'}, [
                Builder.node('div', {id: 'meangrade'+this.area, className: 'meangrade'}, ''),
                Builder.node('div', {id: 'takeexam'+this.area, className: 'takeexam', onclick: 'Globals.modules["'+this.area+'"].takeExam()'}, 'Take exam')
            ])
        ]);
        
        return newDiv;
    },
    
    display: function() {
        selfDiv = this.createDiv();
        if (this.area == "comp" || this.area == "trash")
            $('module-box').insertBefore(selfDiv, $('module-box-0'));
        else
            $('module-box-'+(Globals.nextModuleBox++%3)).appendChild(selfDiv);        
    },
    
    takeExam: function(type) {
        if (!type && this.moduleExam) {
            // Remove existing exam
            this.moduleExam = false;
            this.oralExam = false;
            
            $("takeexam"+this.area).innerHTML = "Take Exam";
            new Effect.BlindUp("modexam"+this.area, {duration: .3});
            setTimeout("Element.removeClassName($('mod"+this.area+"'), 'hasexam');", 300);
            setTimeout('$("mod'+this.area+'").removeChild($("modexam'+this.area+'"))', 300);
            
            this.update();
            
        } else if (!type) {
            this.update();
        
            if (this.compCredits < this.maxCompCredits || this.optCredits < this.maxOptCredits) {
                var missingphrase = ""
                if (this.compCredits < this.maxCompCredits) missingphrase += (this.maxCompCredits-this.compCredits)+" compulsory credits";
                if (this.compCredits < this.maxCompCredits && this.optCredits < this.maxOptCredits) missingphrase += " and ";
                if (this.optCredits < this.maxOptCredits) missingphrase += (this.maxOptCredits-this.optCredits)+" optional compulsory credits";
                var body = Local.info_not_enough_credits.replace("$1", missingphrase).replace("$2", this.name);
                Message.warning(Local.title_not_enough_credits, body);            
            } else {
                // Enough credits. Count Number of module exams.
                var totalExams = 0;
                var certExams = 0;
            
                for (mid in Globals.modules) {
                    if (Globals.modules[mid].moduleExam) {
                        totalExams++;
                        if (!Globals.modules[mid].oralExam) certExams++;
                    }
                }
            
                if (totalExams >= 5) body = Local.info_five_exams;
            
                else if (certExams>=2) {
                    var body = Local.info_only_oral_exam.replace("$1", this.name)
                    body += "<div class='query' onclick='Globals.modules[\""+this.area+"\"].takeExam(\"oral\");'>"+Local.button_oral+"</div>\n";                
                } else {        
                    var body = Local.info_which_exam.replace("$1", this.name).replace("$2", grade2str(this.grade));
                    body += "<div class='query' onclick='Globals.modules[\""+this.area+"\"].takeExam(\"cert\");'>"+Local.button_cert+"</div>\n";
                    body += "<div class='query' onclick='Globals.modules[\""+this.area+"\"].takeExam(\"oral\");'>"+Local.button_oral+"</div>\n";        
                }
                Message.warning(Local.title_exam, body);
            }
        } else if (type=="cert") {
            Message.hide();
            this.moduleExam = true;
            this.addExamDiv();
        } else if (type=="oral") {
            Message.hide();
            this.moduleExam = true;
            this.oralExam = true;
            this.addExamDiv();
        }
        Sidebar.update();
    },
    
    addExamDiv: function() {
        $("takeexam"+this.area).innerHTML = "Remove Exam";
        Element.addClassName($('mod'+this.area), 'hasexam');
        if (this.oralExam) {
            var slider = Builder.node('div', {id:'mtrack'+this.area, className: 'slidetrack'}, [
                Builder.node('div', {id:'mhandle'+this.area, className: 'slidehandle'}),
            ]);

            var examDiv = Builder.node('div', {id: 'modexam'+this.area, className: 'exam'}, [
                Builder.node('div', {id:'mgrade'+this.area, className: 'grade'}, grade2str(this.grade)),
                Builder.node('p', 'Module Exam (oral)'),            
                slider
            ]);

            $("mod"+this.area).appendChild(examDiv);

            // create the slider object for that module exam
            var gradeSlide = new Control.Slider('mhandle'+this.area, 'mtrack'+this.area, {
              range: $R(1.0,4.0),
              sliderValue: 2.0,
              axis:'horizontal',
              alignX: -20,
              alignY: 0,
              id: this.area,
              parent: this,
              values: [1.0, 1.3, 1.7, 2.0, 2.3, 2.7, 3.0, 3.3, 3.7, 4.0],
              onSlide: function(v){
                    this.parent.grade = v;
                    this.parent.update();
                    $('mgrade'+this.id).innerHTML = grade2str(v);
                  }
            });

        } else {
            var examDiv = Builder.node('div', {id: 'modexam'+this.area, className: 'exam'}, [
               Builder.node('div', {id:'mgrade'+this.area, className: 'grade'}, grade2str(this.grade)),
                Builder.node('p', 'Module Exam (certificates)')
            ]);
            $("mod"+this.area).appendChild(examDiv);
        }
        
    },
    
    countCredits: function() {
        this.compCredits = 0;
        this.optCredits = 0;
        gradeCredits = 0;
        grade = 0;
        for (courseHash in Globals.courses) {
            course = Globals.courses[courseHash]
            if (course.module == this.area) {
                if (course.comp) this.compCredits += course.credits;
                else this.optCredits += course.credits;
                if (course.grade != 0) {
                    gradeCredits += course.credits;
                    grade += course.credits * course.grade;
                }
            }
        }
        if (gradeCredits > 0) grade = grade / gradeCredits;
        
        grade = Math.round(grade * 10) / 10;
        
        if (!this.moduleExam || !this.oralExam) this.grade = grade;
        
    },
    
    update: function() {
        // If this is the trash: destroy the course
        if (this.area == "trash") {
            for (hash in Globals.courses) {
                if (Globals.courses[hash].module == this.area) Globals.courses[hash].destroy();
            }
        } else {
            this.countCredits();
            
            $("compfield"+this.area).innerHTML = "Compulsory: "+this.compCredits+" / "+this.maxCompCredits;
            $("optfield"+this.area).innerHTML = "Optional: "+this.optCredits+" / "+this.maxOptCredits;
            $('meangrade'+this.area).innerHTML = "&empty; "+grade2str(this.grade);
        
            if (this.optCredits > this.maxOptCredits && this.compCredits >= this.maxCompCredits) {
                $("optfield"+this.area).addClassName("error");
                if ($("optfield"+this.area).attachEvent ){
                   $("optfield"+this.area).attachEvent('onclick', 'Message.moduleFull('+this.optCredits+', '+this.maxOptCredits+');');
                } else {
                   $("optfield"+this.area).setAttribute('onclick', 'Message.moduleFull('+this.optCredits+', '+this.maxOptCredits+');');
                }
            } else {
                $("optfield"+this.area).removeClassName("error");
            }
        
            // Check if we have enough credits for an exam
            if (this.optCredits >= this.maxOptCredits && this.compCredits >= this.maxCompCredits) {
                Element.addClassName($('takeexam'+this.area), 'enabled');
            } else {
                Element.removeClassName($('takeexam'+this.area), 'enabled');
                if (this.moduleExam) this.takeExam();
            }
                
            if (this.moduleExam && ! this.oralExam) $('mgrade'+this.area).innerHTML = grade2str(this.grade);

        }
        Sidebar.update();
    }
    
});
